﻿using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Linq;

namespace ProxySourceGenerator
{

    /// <summary>
    /// ProxyGenerator
    /// </summary>
    [Generator]
    public class ProxyGenerator : ISourceGenerator
    {
        /// <summary>
        /// <inheritdoc/>
        /// </summary>
        public void Initialize(GeneratorInitializationContext context)
        {
            System.Diagnostics.Debugger.Launch();
            context.RegisterForSyntaxNotifications(() => new MySyntaxReceiver());
        }

        /// <summary>
        /// <inheritdoc/>
        /// </summary>
        public void Execute(GeneratorExecutionContext context)
        {
            if (context.SyntaxReceiver is not MySyntaxReceiver receiver)
                return;


            var symbolList = receiver.SyntaxNodeList.Select(m => context.Compilation.GetSemanticModel(m.SyntaxTree).GetDeclaredSymbol(m) as INamedTypeSymbol)
                .Where(m => m != null && !m.IsAbstract && !m.IsStatic);
            foreach ( var symbol in symbolList)
            {
                var ns = symbol.ContainingNamespace.ToDisplayString(); 
                //var properties = symbol.
            }
            
            
        }

        #region private method
        /// <summary>
        /// test execute 1
        /// </summary>
        private void Execute1(GeneratorExecutionContext context)
        {
            var compliation = context.Compilation;
            foreach (var syntaxTree in compliation.SyntaxTrees)
            {
                var semanticModel = compliation.GetSemanticModel(syntaxTree);
                var nodes = syntaxTree.GetRoot().DescendantNodes().Where(m => m.IsKind(SyntaxKind.InterfaceDeclaration) || m.IsKind(SyntaxKind.ClassDeclaration));
                foreach (var node in nodes)
                {
                    var str = node.ToFullString();
                    var symbol = semanticModel.GetDeclaredSymbol(node) as INamedTypeSymbol;
                    var nspace = symbol.ContainingNamespace;
                    var baseType = symbol.BaseType;
                    var interfaces = symbol.Interfaces;
                    var members = symbol.GetMembers();
                    foreach (var member in members)
                    {
                        if (member is IMethodSymbol method)
                        {
                            var isFunc = method.MethodKind != MethodKind.PropertyGet && method.MethodKind != MethodKind.PropertySet;
                            var paramters = method.Parameters;
                            var returnType = method.ReturnType;
                        }
                    }
                }

            }
        }

        /// <summary>
        /// test execute 2
        /// </summary>
        private void Execute2(GeneratorExecutionContext context)
        {
            var mainMethod = context.Compilation.GetEntryPoint(context.CancellationToken);
            var source = $@"
using System;

namespace {mainMethod.ContainingNamespace.ToDisplayString()}
{{
    public static partial class {mainMethod.ContainingType.Name}
    {{
        static partial void HelloFrom(string name)
        {{
            Console.WriteLine($""Generator says: Hi from '{{name}}'"");
        }}
    }}
}}
";
            context.AddSource("generator1", source);
        }
        #endregion
    }
}